package ltd.sshine.bot.config.Util;

import ltd.sshine.bot.config.scan.EventHandlerFactory;
import ltd.sshine.bot.config.scan.EventHandlerMappingFactory;
import ltd.sshine.bot.config.scan.EventHandlerMappingResolver;
import net.mamoe.mirai.contact.Contact;
import net.mamoe.mirai.contact.User;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.MessageChain;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;

public class EventUtil {

  static  {
       EventHandlerMappingResolver eventHandlerMappingResolver = new EventHandlerMappingResolver();
       eventHandlerMappingResolver.scanPackages( new String[]{"ltd.sshine.bot.Event"});
   }
   public static void run(String event, MessageEvent msgevent){
       Method handlerMethod = EventHandlerMappingFactory.getMethodMapping(event);
       if(handlerMethod==null) return;
       Object eventObj = EventHandlerFactory.get(handlerMethod.getDeclaringClass().getName());
       try {
           invokeHandlerMethod(eventObj,handlerMethod,msgevent);
       } catch (Throwable throwable) {
           exce(msgevent);
           throwable.printStackTrace();
       }
   }

    public static void invokeHandlerMethod(Object object, Method method, MessageEvent msgevent)
            throws Throwable {
        Object result;
        if (method != null) {
            Parameter[] params = method.getParameters();
            Object[] args=new Object[params.length];
            for(int i=0;i< params.length;i++){
                if (params[i].getType().equals(MessageEvent.class)){
                    args[i]=msgevent;
                }else if(params[i].getType().equals(User.class)){
                    args[i]=msgevent.getSender();
                }else if(params[i].getType().equals(Contact.class)){
                    args[i]=msgevent.getSubject();
                }else if(params[i].getType().equals(String[].class)){
                    String[] s = msgevent.getMessage().get(1).toString().split("\\s");
                    args[i]= s.length!=1?Arrays.copyOfRange(s,1,s.length-1):null;
                }else if(params[i].getType().equals(MessageChain.class)){
                    args[i]=msgevent.getMessage();
                }
                else if(params[i].getType().equals(String.class)){
                    String[] s = msgevent.getMessage().get(1).toString().split("\\s");
                    args[i]= s.length!=1? msgevent.getMessage().get(1).toString().substring(s[0].length()+1)  :null;
                }
            }
            try {
                result = method.invoke(object,args);
                if (result!=null){
                    if(result instanceof MessageChain){
                        msgevent.getSubject().sendMessage((MessageChain)result);
                    }else{
                        msgevent.getSubject().sendMessage(result.toString());
                    }
                }
            } catch (InvocationTargetException e) {
                throw e.getTargetException();
            }
        }
    }

    public static void exce(MessageEvent msgevent){
        Contact sender = msgevent.getSubject();
        sender.sendMessage("服务器错误");
    }
}
